# Author: Yu Bin
# Date: 2024/12/30 18:52:23
# E-mail: 853823259@qq.com
# 1、练习封装案例（和上课保持一致即可）
class Person:

    def __init__(self, name, weight):
        self.name = name
        self.weight = weight

    def __str__(self):
        return "我的名字叫 %s 体重 %.2f 公斤" % (self.name, self.weight)

    def run(self):
        """跑步"""
        print("%s 爱跑步， 跑步锻炼身体" % self.name)
        self.weight -= 0.5

    def eat(self):
        """吃东西"""
        print("%s 是吃货， 吃完这顿再减肥" % self.name)
        self.weight += 1


xiaoming = Person("大象", 75)
xiaoming.run()
xiaoming.eat()
xiaoming.eat()
print(xiaoming)
# 老虎爱跑步
xiaomei = Person("老虎", 45)
xiaomei.eat()
xiaomei.run()
print(xiaomei)
print(xiaoming)
print("-" * 100)


# 摆放家具

class HouseItem:
    def __init__(self, name, area):
        self.name = name
        self.area = area

    def __str__(self):
        return "[%s] 占地 %.2f" % (self.name, self.area)


class House:
    def __init__(self, house_type, area):
        self.house_type = house_type
        self.area = area
        # 剩余面积
        self.free_area = area
        # 家具名称列表
        self.item_list = []

    def __str__(self):
        # Python 能够自动的将一对括号内部的代码连接在一起
        return ("户型： %s\n 总面积： %.2f[剩余： %.2f]\n 家具： %s"
                % (self.house_type, self.area,
                   self.free_area, self.item_list))

    def add_item(self, item):
        print("要添加 %s" % item)
        # 1. 判断家具面积是否大于剩余面积
        if item.area > self.free_area:
            print("%s 的面积太大， 不能添加到房子中" % item.name)
            return
        # 2. 将家具的名称追加到名称列表中
        self.item_list.append(item.name)
        # 3. 计算剩余面积
        self.free_area -= item.area


# 1. 创建家具
bed = HouseItem("席梦思", 4)
chest = HouseItem("衣柜", 2)
table = HouseItem("餐桌", 1.5)
print(bed)
print(chest)
print(table)
# 2. 创建房子对象
my_home = House("两室一厅", 60)
my_home.add_item(bed)
my_home.add_item(chest)
my_home.add_item(table)
print(my_home)
print("-" * 100)


# 士兵突击
class Gun:
    def __init__(self, model):
        # 枪的型号
        self.model = model
        # 子弹数量
        self.bullet_count = 0

    def add_bullet(self, count):
        self.bullet_count += count

    def shoot(self):
        # 判断是否还有子弹
        if self.bullet_count <= 0:
            print("没有子弹了...")
            return
        # 发射一颗子弹
        self.bullet_count -= 1
        print("%s 发射子弹[%d]..." % (self.model, self.bullet_count))


class Soldier:
    def __init__(self, name):
        # 1. 姓名
        self.name = name
        # 2. 枪 - 新兵没有枪
        self.gun = None

    def fire(self):
        # 1. 判断士兵是否有枪
        # if self.gun == None:
        if self.gun is None:
            print("[%s] 还没有枪..." % self.name)
            return
        # 2. 高喊口号
        print("冲啊...[%s]" % self.name)
        # 3. 让枪装填子弹
        self.gun.add_bullet(50)
        # 4. 让枪发射子弹
        self.gun.shoot()


# 创建枪对象
ak47 = Gun("AK47")
# 创建许三多
xusanduo = Soldier("许三多")
xusanduo.fire()
xusanduo.gun = ak47
xusanduo.fire()
xusanduo.fire()
print(xusanduo.gun)


# 2、练习私有属性和私有方法（和上课保持一致即可）
class Women:
    """
    私有属性和私有方法只能在类内部访问
    """

    def __init__(self, name, age):
        self.name = name
        self.__age = age

    def __secret(self):
        print(f'{self.name} 年龄{self.__age}')

    def boyfriend(self):
        self.__secret()


if __name__ == '__main__':
    xiaohong = Women('小红', 18)
    print(xiaohong.name)
    xiaohong.boyfriend()


# 3、练习单继承，多重继承案例（和上课保持一致即可）
class Animal:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return "我的名字叫%s" % self.name

    def eat(self):
        print("吃")

    def drink(self):
        print("喝")

    def run(self):
        print("跑")

    def sleep(self):
        print("睡")


class Dog(Animal):
    def bark(self):
        print("叫")


wangcai = Dog("旺财")
print(wangcai)
wangcai.bark()
wangcai.sleep()
wangcai.run()


class Parent:
    def __init__(self, height):
        self.height = height


class Son1(Parent):
    def __init__(self, age, *args):
        self.age = age
        super().__init__(*args)


class Son2(Parent):
    def __init__(self, score, *args):
        self.score = score
        super().__init__(*args)


class Grandson(Son1, Son2):
    def __init__(self, name, *args):
        self.name = name
        super().__init__(*args)


xiaoming = Grandson('小明', 18, 98.5, 175)  # 姓名，年龄，分数
print(xiaoming.name)
print(xiaoming.age)
print(xiaoming.score)
print(xiaoming.height)


# 4、实现单例模式（和上课保持一致即可）
class MusicPlayer:
    instance = None  # 用来保存对象的

    def __new__(cls, *args, **kwargs):
        # 1.创建对象，分配空间
        if cls.instance is None:
            cls.instance = super().__new__(cls)
        return cls.instance

    def __init__(self, name):
        self.name = name


player1 = MusicPlayer('七里香')
player2 = MusicPlayer('东风破')
print(id(player1))
print(id(player2))
print(player1.name)
print(player2.name)

# 5、通过try进行异常捕捉，确保输入的内容一定是一个整型数，然后判断该整型数是否是对称数，12321就是对称数，123321也是对称数，否则就打印不是，非整型抛异常，不是对称数抛异常
while True:
    try:
        num = int(input("请输入一个整数"))
    except ValueError:
        print("请输入正确的整数")
    else:
        try:
            if (str(num) != str(num)[::-1]):
                ex = Exception("该数不是对称数")
                raise ex
            else:
                print("该数是对称数")
                break
        except Exception as e:
            print(e)
            break
